home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 November: Tool Chest / Dev.CD Nov 98 TC.toast / Sample Code / Snippets / Development Tools & Languages / MouseInfo / UMenuedWindow.cp < prev    next >
Encoding:
Text File  |  1995-02-04  |  10.5 KB  |  425 lines  |  [TEXT/MPS ]

  1. /*
  2.  *    UMenuedWindow.cp
  3.  *
  4.  *    Copyright 1991 Imagenetics
  5.  *    All rights reserved
  6.  *
  7.  *    19 Aug 91  EMB  Created file
  8.  *    22 Aug 91  EMB  Modified design to be standalone unit
  9.  *     1 Oct 91  LPG  Changed Str255 to CStr255 (MacApp 3.0ß2)
  10.  *                    Catch empty strings in AddToWindowMenu
  11.  *
  12.  */
  13.  
  14. #ifndef        __UMENUEDWINDOW__
  15. #include    "UMenuedWindow.h"
  16. #endif
  17.  
  18. #ifndef __UBEHAVIOR__
  19. #include <UBehavior.h>
  20. #endif
  21.  
  22. #ifndef __UAPPLICATION__
  23. #include <UApplication.h>
  24. #endif
  25.  
  26. #ifndef __UMENUMGR__
  27. #include <UMenuMgr.h>
  28. #endif
  29.  
  30. class TMenuedWindowBehavior : public TBehavior
  31. {
  32.     DeclareClass(TMenuedWindowBehavior);
  33.     
  34. private:
  35.     TList*    fWindowsMenuData;
  36.  
  37.     short    fMenuID;
  38.     short    fFirstItem;
  39. public:
  40.  
  41.     // Construction/Destruction
  42.     virtual void    Free();                                        //    OVERRIDE
  43.     virtual void    IMenuedWindowBehavior(short menuID);
  44.  
  45.     TMenuedWindowBehavior() {this->Initialize();}
  46.     virtual void    Initialize();                                //    OVERRIDE
  47.  
  48.     // Menu Commands
  49.     virtual void    DoMenuCommand(CommandNumber aCommand);        //    OVERRIDE
  50.     virtual void    DoSetupMenus();                                //    OVERRIDE
  51.  
  52.     // Window menu
  53.     virtual void        AddToWindowMenu(TWindow* aWindow);
  54.     virtual void        DeleteFromWindowMenu(TWindow* aWindow);
  55.     virtual TWindow*    MenuItemToWindow(short menuItem);
  56.     virtual void        SelectWindowMenuWindow(short itemNo);
  57.     virtual short    WindowToMenuItem(TWindow* aWindow);
  58. };
  59.  
  60.  
  61. /*********************************************************************************************
  62.     U M e n u e d W i n d o w    G l o b a l    R o u t i n e s
  63. *********************************************************************************************/
  64.  
  65. TMenuedWindowBehavior*    gMenuedWindowBehavior = NULL;
  66.  
  67. //--------------------------------------------------------------------------------------------------
  68. #pragma segment AInit
  69.  
  70. void InitUMenuedWindow(ResNumber menuID)
  71. {
  72.     gMenuedWindowBehavior = NULL;
  73.  
  74.     macroDontDeadStrip(TFloatMenuedWindow);
  75.     macroDontDeadStrip(TMenuedWindow);
  76.  
  77.     if (gApplication == NULL)
  78.     {
  79.         if (qDebug)
  80.             ProgramBreak("InitUMenuedWindow must be called in or after your IMyApplication method");
  81.         Failure(minErr, 0);
  82.     }
  83.  
  84.     gMenuedWindowBehavior = new TMenuedWindowBehavior;
  85.     gMenuedWindowBehavior->IMenuedWindowBehavior(menuID);
  86.     gApplication->AddBehavior(gMenuedWindowBehavior);
  87. }
  88.  
  89. //--------------------------------------------------------------------------------------------------
  90. /*
  91.  *    In the spirit of SetCommandName and SetCommandIcon we have another utility
  92.  *    routine to handle the menu item style
  93.  */
  94. #pragma segment MAUtilitiesRes
  95.  
  96. void SetCommandStyle(CommandNumber aCommand, short chStyle)
  97. {
  98.     ResNumber    menu;
  99.     short        item;
  100.     MenuHandle    aMenuHandle;
  101.  
  102.     aMenuHandle = CommandToComponents(aCommand, menu, item);
  103.     if (aMenuHandle)
  104.         ::SetItemStyle(aMenuHandle, item, chStyle);
  105. }
  106.  
  107.  
  108. /*********************************************************************************************
  109.     T M e n u e d W i n d o w C o H a n d l e r
  110. *********************************************************************************************/
  111.  
  112. //--------------------------------------------------------------------------------------------------
  113. #pragma segment ARes
  114.  
  115. #undef Inherited
  116. #define Inherited TBehavior
  117. DefineClass(TMenuedWindowBehavior, Inherited);
  118.  
  119. void TMenuedWindowBehavior::AddToWindowMenu(TWindow* aWindow)
  120. {
  121.     CStr255        itsTitle;
  122.  
  123.     aWindow->GetTitle(itsTitle);
  124.  
  125.     if (itsTitle.IsEmpty())
  126.         itsTitle = " ";        // AppendMenu doesn't like empty strings.
  127.  
  128.     ::AppendMenu(MAGetMenu(fMenuID), itsTitle);
  129.  
  130.     fWindowsMenuData->InsertLast(aWindow);
  131. }
  132.  
  133.  
  134. //--------------------------------------------------------------------------------------------------
  135. #pragma segment ASelCommand
  136.  
  137. void TMenuedWindowBehavior::DoMenuCommand(CommandNumber aCommand)        // OVERRIDE
  138. {
  139.     short    itsMenuID;
  140.     short    itsMenuItem;
  141.  
  142.     if (aCommand < 0)
  143.     {
  144.         CommandToMenuItem(aCommand, itsMenuID, itsMenuItem);
  145.         if (itsMenuID == fMenuID)
  146.             this->SelectWindowMenuWindow(itsMenuItem);
  147.         else
  148.             Inherited::DoMenuCommand(aCommand);
  149.     }
  150.     else
  151.         Inherited::DoMenuCommand(aCommand);
  152. }
  153.  
  154.  
  155. //--------------------------------------------------------------------------------------------------
  156. #pragma segment ARes
  157.  
  158. void TMenuedWindowBehavior::DoSetupMenus()        // OVERRIDE
  159. {
  160.     CommandNumber    itsCommandNumber;
  161.     TWindow*        itsWindow = NULL;
  162.     short            frontMenuItem;
  163.     CStr255            itsTitle;
  164.     short            itsMenuItem;
  165.     short            i;
  166.  
  167.     Inherited::DoSetupMenus();
  168.  
  169.     //    Enable the variant portion of the windows menu
  170.     frontMenuItem = this->WindowToMenuItem(gApplication->GetActiveWindow(false));
  171.     for (i = short(fWindowsMenuData->GetSize()); i > 0; i--)
  172.     {
  173.         itsMenuItem = i + (fFirstItem - 1);
  174.         itsCommandNumber = CommandFromMenuItem(fMenuID, itsMenuItem);
  175.         itsWindow = this->MenuItemToWindow(itsMenuItem);
  176.  
  177.         //    Enable the item, checking if it is the front item
  178.         EnableCheck(itsCommandNumber, true, itsMenuItem == frontMenuItem);
  179.  
  180.         //    Make sure the name is up-to-date
  181.         itsWindow->GetTitle(itsTitle);
  182.         SetCommandName(itsCommandNumber, itsTitle);
  183.  
  184.         //    Make the item style plain if it is visible, italics if hidden
  185.         if (itsWindow->IsShown())
  186.             SetCommandStyle(itsCommandNumber, normal);
  187.         else
  188.             SetCommandStyle(itsCommandNumber, italic);
  189.  
  190.         itsWindow = NULL;
  191.     }
  192. }
  193.  
  194. //--------------------------------------------------------------------------------------------------
  195. #pragma segment ARes
  196.  
  197. void TMenuedWindowBehavior::DeleteFromWindowMenu(TWindow* aWindow)
  198. {
  199.     short    itsMenuItem;
  200.  
  201.     if (aWindow)
  202.     {
  203.         itsMenuItem = this->WindowToMenuItem(aWindow);
  204.  
  205.         if (itsMenuItem != kEmptyIndex)
  206.             ::DeleteMenuItem(MAGetMenu(fMenuID), itsMenuItem);
  207.  
  208.         fWindowsMenuData->Delete(aWindow);
  209.     }
  210. }
  211.  
  212. //--------------------------------------------------------------------------------------------------
  213. #pragma segment ATerminate
  214.  
  215. void TMenuedWindowBehavior::Free()                        // OVERRIDE
  216. {
  217.     fWindowsMenuData = (TList*)FreeIfObject(fWindowsMenuData);
  218.  
  219.     Inherited::Free();
  220. }
  221.  
  222. //--------------------------------------------------------------------------------------------------
  223. #pragma segment AInit
  224.  
  225. void TMenuedWindowBehavior::IMenuedWindowBehavior(short menuID)
  226. {
  227.     FailInfo    fi;
  228.  
  229.     this->IBehavior(kMenuedWindowBehavior);
  230.  
  231.     Try(fi)
  232.     {
  233.         fWindowsMenuData = NewList();
  234.         if (qDebug)
  235.             fWindowsMenuData->SetEltType("TWindow");
  236.  
  237.         fMenuID = menuID;
  238.         fFirstItem = ::CountMItems(MAGetMenu(menuID)) + 1;
  239.  
  240.         fi.Success();
  241.     }
  242.     else
  243.     {
  244.         this->Free();
  245.         fi.ReSignal();
  246.     }
  247. }
  248.  
  249. //--------------------------------------------------------------------------------------------------
  250. #pragma segment AInit
  251.  
  252. void TMenuedWindowBehavior::Initialize()                    // OVERRIDE
  253. {
  254.     fWindowsMenuData = NULL;
  255.     fMenuID = 0;
  256.     fFirstItem = 0;
  257. }
  258.  
  259. //--------------------------------------------------------------------------------------------------
  260. #pragma segment ARes
  261.  
  262. TWindow* TMenuedWindowBehavior::MenuItemToWindow(short menuItem)
  263. {
  264.     TWindow*    result = NULL;
  265.     ArrayIndex    windowIndex;
  266.  
  267.     if (menuItem > 0)
  268.     {
  269.         windowIndex = menuItem - (fFirstItem - 1);
  270.         if (windowIndex > kEmptyIndex  &&  windowIndex <= fWindowsMenuData->GetSize())
  271.             result = (TWindow*)fWindowsMenuData->At(windowIndex);
  272.     }
  273.  
  274.     return result;
  275. }
  276.  
  277. //--------------------------------------------------------------------------------------------------
  278. #pragma segment ARes
  279.  
  280. void TMenuedWindowBehavior::SelectWindowMenuWindow(short itemNo)
  281. {
  282.     TWindow*    itsWindow;
  283.  
  284.     if (itemNo > 0)
  285.     {
  286.         itsWindow = this->MenuItemToWindow(itemNo);
  287.         if (itsWindow)
  288.         {
  289.             if (!itsWindow->IsShown())
  290.                 itsWindow->Open();
  291.             itsWindow->Select();
  292.         }
  293.         else if (qDebug)
  294.             ProgramBreak("Problem: I’ve been asked to select a Windows menu window that doesn’t exist");
  295.     }
  296. }
  297.  
  298. //--------------------------------------------------------------------------------------------------
  299. #pragma segment ARes
  300.  
  301. short TMenuedWindowBehavior::WindowToMenuItem(TWindow* aWindow)
  302. {
  303.     short    result = 0;
  304.     short    windowIndex;
  305.  
  306.     if (aWindow)
  307.     {
  308.         //    The fourth item is the first one placed in the windows menu (and hence
  309.         //    tracked in fWindowsMenuData.
  310.         windowIndex = short(fWindowsMenuData->GetIdentityItemNo(aWindow));
  311.         if (windowIndex != kEmptyIndex)
  312.             result = windowIndex + (fFirstItem - 1);
  313.     }
  314.  
  315.     return result;
  316. }
  317.  
  318. /*********************************************************************************************
  319.     T F l o a t M e n u e d W i n d o w
  320. *********************************************************************************************/
  321.  
  322. #pragma segment AOpen
  323.  
  324. #undef Inherited
  325. #define Inherited TFloatWindow
  326. DefineClass(TFloatMenuedWindow, Inherited);
  327.  
  328. void TFloatMenuedWindow::DoPostCreate(TDocument* itsDocument)        // OVERRIDE
  329. {
  330.     Inherited::DoPostCreate(itsDocument);
  331.  
  332.     if (gMenuedWindowBehavior)
  333.         gMenuedWindowBehavior->AddToWindowMenu(this);
  334. }
  335.  
  336. //--------------------------------------------------------------------------------------------------
  337. #pragma segment AClose
  338.  
  339. void TFloatMenuedWindow::Free()                                        // OVERRIDE
  340. {
  341.     if (gMenuedWindowBehavior)
  342.         gMenuedWindowBehavior->DeleteFromWindowMenu(this);
  343.  
  344.     Inherited::Free();
  345. }
  346.  
  347. //--------------------------------------------------------------------------------------------------
  348. #pragma segment AOpen
  349.  
  350. void TFloatMenuedWindow::IFloatMenuedWindow(TDocument* itsDocument,
  351.                                        WindowPtr itsWMgrWindow, Boolean canResize,
  352.                                        Boolean canClose, Boolean disposeOnFree)
  353. {
  354.  
  355.     this->IFloatWindow(itsDocument, itsWMgrWindow, canResize, canClose, disposeOnFree);
  356.  
  357.     FailInfo    fi;
  358.     Try(fi)
  359.     {
  360.         if (gMenuedWindowBehavior)
  361.             gMenuedWindowBehavior->AddToWindowMenu(this);
  362.  
  363.         fi.Success();
  364.     }
  365.     else
  366.     {
  367.         this->Free();
  368.         fi.ReSignal();
  369.     }
  370. }
  371.  
  372. /*********************************************************************************************
  373.     T M e n u e d W i n d o w
  374. *********************************************************************************************/
  375. #pragma segment AOpen
  376.  
  377. #undef Inherited
  378. #define Inherited TWindow
  379. DefineClass(TMenuedWindow, Inherited);
  380.  
  381. void TMenuedWindow::DoPostCreate(TDocument* itsDocument)            // OVERRIDE
  382. {
  383.     Inherited::DoPostCreate(itsDocument);
  384.  
  385.     if (gMenuedWindowBehavior)
  386.         gMenuedWindowBehavior->AddToWindowMenu(this);
  387. }
  388.  
  389.  
  390. //--------------------------------------------------------------------------------------------------
  391. #pragma segment AClose
  392.  
  393. void TMenuedWindow::Free()                                        // OVERRIDE
  394. {
  395.     if (gMenuedWindowBehavior)
  396.         gMenuedWindowBehavior->DeleteFromWindowMenu(this);
  397.  
  398.     Inherited::Free();
  399. }
  400.  
  401. //--------------------------------------------------------------------------------------------------
  402. #pragma segment AOpen
  403.  
  404. void TMenuedWindow::IMenuedWindow(TDocument* itsDocument, WindowPtr itsWMgrWindow,
  405.                              Boolean canResize, Boolean canClose,
  406.                              Boolean disposeOnFree)
  407. {
  408.  
  409.     this->IWindow(itsDocument, itsWMgrWindow, canResize, canClose, disposeOnFree);
  410.  
  411.     FailInfo    fi;
  412.     Try(fi)
  413.     {
  414.         if (gMenuedWindowBehavior)
  415.             gMenuedWindowBehavior->AddToWindowMenu(this);
  416.  
  417.         fi.Success();
  418.     }
  419.     else
  420.     {
  421.         this->Free();
  422.         fi.ReSignal();
  423.     }
  424. }
  425.